DeepWiki

07.b - UI-Components-&-Animations

Relevant source files

This document describes the reusable UI components and animation system used throughout the godeep.wiki frontend. The components implement interactive visual effects including hover states, mouse tracking, intersection-observer-based animations, and custom CSS keyframes. For information about the overall frontend architecture and routing structure, see 7. For information about theming and layout structure, see 7.1.


The UI component system consists of two categories: interactive components with hover effects and mouse tracking (BeamButton, SpotlightCard, IconGlow), and animation components that orchestrate entrance effects (FadeIn, BackgroundReveal). All components are client-side rendered using the "use client" directive and follow a composition pattern where they wrap child elements to enhance them with visual effects.

Component Architecture Diagram

Sources: app/page.tsx L1-L214

components/beam-button.tsx L1-L26

components/spotlight-card.tsx L1-L68

components/icon-glow.tsx L1-L20

components/fade-in.tsx L1-L55

components/background-reveal.tsx L1-L18

app/globals.css L128-L158


The BeamButton component wraps the shadcn/ui Button component with an animated gradient border effect that appears on hover. It creates a glowing "beam" effect using a blurred gradient background that fades in when the user hovers over the button.

Component Props:

PropTypeDescription
childrenReact.ReactNodeButton content (text, icons, etc.)
classNamestring (optional)Additional CSS classes to merge with defaults
...propsReact.ComponentProps<typeof Button>All standard Button props (type, size, etc.)

Implementation Details:

The component structure consists of three layers defined in components/beam-button.tsx L11-L24

:

  1. Outer wrapper (div with relative group inline-flex): Establishes positioning context and hover group
  2. Gradient background (div with absolute -inset-0.5): Animated blur gradient that expands on hover, using bg-gradient-to-r from-blue-500 to-purple-600 with opacity-0 transitioning to opacity-100 on group-hover
  3. Button element: Styled with blue background, rounded-full shape, custom shadow effects, and border that becomes visible on hover

The glow effect is achieved through CSS shadow properties that intensify on hover:

  • Default: shadow-[0_0_20px_-5px_rgba(37,99,235,0.3)]
  • Hover: shadow-[0_0_25px_-5px_rgba(37,99,235,0.5)]

Usage Example:

The component is used in app/page.tsx L63-L66

for the primary CTA button and app/page.tsx L182-L184

for the pricing CTA:

<form action={createCheckoutSession}>  <BeamButton size="lg" type="submit">    Generate DeepWiki — $10  </BeamButton></form>

Sources: components/beam-button.tsx L1-L26

app/page.tsx L63-L66

app/page.tsx L182-L184

The SpotlightCard component creates a card with an interactive "spotlight" effect that follows the user's mouse cursor. It renders two radial gradients that track mouse position: a subtle background glow and a more focused border highlight.

Component Props:

PropTypeDescription
childrenReact.ReactNodeCard content to be wrapped
classNamestring (optional)Additional CSS classes (defaults to "")

Mouse Tracking Implementation:

The component uses React refs and state to track mouse position, as shown in components/spotlight-card.tsx L11-L20

:

  1. State management: * position: Stores { x: number, y: number } relative to card bounds * opacity: Controls spotlight visibility (0 when not hovered, 1 when hovered)
  2. Event handlers: * handleMouseMove: Calculates cursor position relative to card bounds using getBoundingClientRect() * handleMouseEnter/handleMouseLeave: Toggle opacity state * handleFocus/handleBlur: Enable keyboard accessibility

Spotlight Rendering:

Two overlaid div elements create the spotlight effect in components/spotlight-card.tsx L48-L63

:

  1. Background glow: Radial gradient with 600px radius, 6% white opacity, 40% transparency fallback
  2. Border highlight: Same radius but 10% opacity, masked with 200px circle using maskImage and WebkitMaskImage for browser compatibility

Both use inline styles with dynamic background properties incorporating position.x and position.y:

radial-gradient(600px circle at ${position.x}px ${position.y}px, rgba(255,255,255,0.06), transparent 40%)

Usage Example:

The component wraps each "What You Get" feature card in app/page.tsx L117-L123

:

<SpotlightCard className="h-full">  <CardContent className="flex flex-col items-center justify-center p-6 space-y-3 text-center h-full">    <item.icon className="w-6 h-6 text-slate-500" />    <span className="text-sm text-slate-300 font-medium">{item.label}</span>  </CardContent></SpotlightCard>

Sources: components/spotlight-card.tsx L1-L68

app/page.tsx L117-L123

The IconGlow component wraps icon elements with a hover-activated glow effect. It provides a consistent visual treatment for all icons in the "How It Works" section.

Component Props:

PropTypeDescription
childrenReact.ReactNodeIcon component to wrap (typically Lucide icons)
classNamestring (optional)Additional CSS classes

Effect Implementation:

The component structure defined in components/icon-glow.tsx L11-L18

uses the group/icon pattern for scoped hover effects:

  1. Outer wrapper: relative group/icon inline-flex establishes hover group context
  2. Glow layer: Absolute positioned div with bg-blue-500/20, blur-lg, transitions from opacity-0 to opacity-100 on group-hover/icon
  3. Icon container: 12x12 rounded square with slate background, slate-800 border that transitions to border-blue-500/50 on hover, and background changes to bg-blue-500/10

The blur radius of the glow layer is blur-lg (16px), creating a soft diffuse effect around the icon container.

Usage Example:

Each step in the "How It Works" section uses IconGlow in app/page.tsx L75-L77

:

<IconGlow className="mx-auto">  <Github className="w-5 h-5 text-slate-400 group-hover/icon:text-blue-400 transition-colors" /></IconGlow>

The icon itself also changes color on hover using the group-hover/icon selector, creating a coordinated visual response.

Sources: components/icon-glow.tsx L1-L20

app/page.tsx L75-L99


The FadeIn component uses the Intersection Observer API to trigger entrance animations when elements scroll into view. It implements a scroll-triggered animation pattern that prevents animations from playing until the element is visible in the viewport.

Component Props:

PropTypeDefaultDescription
childrenReact.ReactNoderequiredContent to animate
classNamestring""Additional CSS classes
delaynumber0Animation delay in milliseconds
durationnumber0.5Animation duration in seconds

Intersection Observer Configuration:

The component sets up an observer in components/fade-in.tsx L16-L39

with these parameters:

const observer = new IntersectionObserver(  ([entry]) => {    if (entry.isIntersecting) {      setIsVisible(true)      observer.unobserve(entry.target)  // Cleanup after triggering    }  },  {    rootMargin: "0px 0px -50px 0px",  // Trigger 50px before bottom edge    threshold: 0.1,                    // Trigger when 10% visible  })

Animation Control:

The component applies the animate-enter class defined in app/globals.css L142-L144

and controls its playback state via inline styles in components/fade-in.tsx L42-L50

:

style={{  animationDelay: `${delay}ms`,  animationDuration: `${duration}s`,  animationPlayState: isVisible ? "running" : "paused",}}

This ensures the animation is paused until the element becomes visible, preventing animations from playing off-screen.

Usage Pattern:

The landing page uses cascading delays to create staggered entrance effects. For example, the hero section in app/page.tsx L34-L68

uses delays of 0ms, 100ms, 200ms, and 300ms:

<FadeIn delay={0}>  <div className="inline-flex items-center...">    <span className="flex h-2 w-2 rounded-full bg-blue-500..."></span>    Think Deep Research for GitHub  </div></FadeIn><FadeIn delay={100}>  <h1 className="text-6xl md:text-8xl...">Your Private Code Wiki</h1></FadeIn><FadeIn delay={200}>  <p className="text-2xl md:text-3xl...">Understand any repository instantly...</p></FadeIn>

The "What You Get" grid uses incremental 50ms delays per item in app/page.tsx L116-L124

:

{items.map((item, i) => (  <FadeIn key={i} delay={i * 50}>    <SpotlightCard className="h-full">...</SpotlightCard>  </FadeIn>))}

Sources: components/fade-in.tsx L1-L55

app/page.tsx L34-L68

app/page.tsx L116-L124

The BackgroundReveal component creates an animated vertical stripe pattern that reveals from top to bottom on page load. It renders six vertical columns that animate sequentially to create a "curtain reveal" effect.

Implementation:

The component in components/background-reveal.tsx L4-L17

generates six columns using array iteration:

<div className="fixed inset-0 z-[-1] flex pointer-events-none">  {[...Array(6)].map((_, i) => (    <div      key={i}      className="flex-1 bg-slate-900/20 border-r border-slate-800/20 animate-reveal"      style={{        animationDelay: `${i * 0.1}s`,      }}    />  ))}</div>

Key Properties:

  • fixed inset-0: Covers entire viewport, fixed positioning
  • z-[-1]: Renders behind all content
  • pointer-events-none: Allows mouse interactions to pass through
  • flex: Equal width columns using flex-1
  • Sequential delays: 0s, 0.1s, 0.2s, 0.3s, 0.4s, 0.5s

The animate-reveal class applies the reveal-down keyframe animation defined in app/globals.css L146-L158

Usage:

The component is rendered once at the top of the landing page layout in app/page.tsx L15

:

<div className="min-h-screen bg-[#0B0C0E]...">  <BackgroundReveal />  {/* Rest of page content */}</div>

Sources: components/background-reveal.tsx L1-L18

app/page.tsx L15

app/globals.css L146-L158


The global stylesheet defines custom CSS keyframe animations and utility classes that power the animation components. These animations use modern CSS properties including transform, filter, and clip-path.

@keyframes enter

Defined in app/globals.css L128-L140

this animation creates a fade-in-up effect with blur:

KeyframeProperties
0%opacity: 0, transform: translateY(10px), filter: blur(4px)
100%opacity: 1, transform: none, filter: none

The animation moves elements 10px upward while fading in and removing a 4px blur, creating a smooth entrance effect. Duration and delay are controlled per-instance via inline styles.

@keyframes reveal-down

Defined in app/globals.css L146-L154

this animation uses clip-path to reveal elements from top to bottom:

KeyframeProperties
0%clip-path: inset(0 0 100% 0) (fully clipped from bottom)
100%clip-path: inset(0 0 0 0) (fully revealed)

The inset() function syntax is inset(top right bottom left). Starting with inset(0 0 100% 0) clips the entire element from the bottom, and animating to inset(0 0 0 0) reveals it downward.

Component-to-Animation Mapping

.animate-enter Class

Defined in app/globals.css L142-L144

:

.animate-enter {  animation: enter 0.6s both;}

The both keyword applies both forwards (maintains final state) and backwards (applies initial state during delay) fill modes. Default duration is 0.6 seconds but can be overridden via inline styles.

.animate-reveal Class

Defined in app/globals.css L156-L158

:

.animate-reveal {  animation: reveal-down 1s cubic-bezier(0.77, 0, 0.175, 1) both;}

The custom cubic-bezier easing function (0.77, 0, 0.175, 1) creates a slow-start, fast-end easing curve that emphasizes the reveal motion. Duration is 1 second.

Sources: app/globals.css L128-L158

components/fade-in.tsx L44

components/background-reveal.tsx L9


The landing page demonstrates a consistent composition pattern where animation components wrap interactive components, which in turn wrap content.

Component Nesting Hierarchy

Pattern Implementation Examples:

  1. Animation + Interactive + Form (app/page.tsx L60-L68 ):
<FadeIn delay={300}>  <div className="pt-4">    <form action={createCheckoutSession}>      <BeamButton size="lg" type="submit">        Generate DeepWiki — $10      </BeamButton>    </form>  </div></FadeIn>
  1. Animation + Interactive + Content (app/page.tsx L116-L124 ):
<FadeIn key={i} delay={i * 50}>  <SpotlightCard className="h-full">    <CardContent className="...">      <item.icon className="w-6 h-6 text-slate-500" />      <span className="text-sm text-slate-300 font-medium">{item.label}</span>    </CardContent>  </SpotlightCard></FadeIn>
  1. Animation + Interactive + Icon (app/page.tsx L74-L79 ):
<FadeIn delay={0} className="space-y-4 group">  <IconGlow className="mx-auto">    <Github className="w-5 h-5 text-slate-400 group-hover/icon:text-blue-400 transition-colors" />  </IconGlow>  <h3 className="text-slate-200 font-medium">Connect GitHub</h3></FadeIn>

Sources: app/page.tsx L60-L68

app/page.tsx L74-L79

app/page.tsx L116-L124


Interactive components manage local UI state using React hooks without requiring global state management. The state is ephemeral and tied to user interactions (mouse position, hover state, visibility).

State Management Comparison Table

ComponentState VariablesState PurposePersistence
BeamButtonNoneUses CSS :hover pseudo-classN/A - CSS-only
SpotlightCardposition: {x, y}, opacity: numberTrack mouse for spotlight effectComponent lifetime only
IconGlowNoneUses CSS group-hover/iconN/A - CSS-only
FadeInisVisible: booleanControl animation playbackComponent lifetime only
BackgroundRevealNonePure CSS animationN/A - CSS-only

SpotlightCard State Flow

FadeIn State Flow

Sources: components/spotlight-card.tsx L11-L36

components/fade-in.tsx L13-L39


The component system implements several performance optimizations:

  1. IntersectionObserver Cleanup: FadeIn automatically unobserves elements after triggering (components/fade-in.tsx L21-L22 ), preventing unnecessary observer callbacks.
  2. Pointer Events Disabling: BackgroundReveal uses pointer-events-none (components/background-reveal.tsx L5 ) to ensure the decorative background doesn't interfere with user interactions.
  3. CSS-Only Hover Effects: BeamButton and IconGlow use pure CSS hover effects without JavaScript, offloading animation work to the browser's compositor thread.
  4. Conditional Ref Checks: Interactive components check for ref existence before accessing properties (components/spotlight-card.tsx L16 ) to prevent errors during unmounting.
  5. Will-Change Optimization: While not explicitly set in the code, the transform and opacity animations automatically trigger GPU acceleration in modern browsers.
  6. Throttled Mouse Tracking: SpotlightCard doesn't throttle mouse move events, but the radial gradient calculations are efficient as they use CSS custom properties updated via inline styles.

Sources: components/fade-in.tsx L21-L22

components/spotlight-card.tsx L15-L20

components/background-reveal.tsx L5

Refresh this wiki

Last indexed: 23 November 2025 (922b35)

On this page

Ask Devin about godeep.wiki-jb

Syntax error in text

mermaid version 11.4.1

07.b - UI-Components-&-Animations | DeepWiki | godeep.wiki